From 4737f7a5d889bde87e52b2f50ed7693d9b410aa7 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 21 Mar 2013 02:08:36 +0100 Subject: [PATCH] Fix crash with v8-bench.js Sometimes the arguments array of the context is provided by the caller and not copied. In that case the address may not be valid anymore after the call, so we need to reset arguments/argumentCount after the call in popContext, otherwise we end up calling mark() on dangling pointers. Also make sure to mark the entire arguments array, not too much and not too little, i.e. use argumentCount. Change-Id: I8b96521b0fb15142ed8c723a9354d275be48cc58 Reviewed-by: Lars Knoll --- src/v4/qv4context.cpp | 9 +++++++-- src/v4/qv4context.h | 2 ++ src/v4/qv4engine.cpp | 5 +++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/v4/qv4context.cpp b/src/v4/qv4context.cpp index 2a7cca3..41b0b2a 100644 --- a/src/v4/qv4context.cpp +++ b/src/v4/qv4context.cpp @@ -264,6 +264,11 @@ bool ExecutionContext::deleteProperty(String *name) return true; } +bool ExecutionContext::needsOwnArguments() const +{ + return function && (function->needsActivation || argumentCount < function->formalParameterCount); +} + void ExecutionContext::destroy(Managed *that) { ExecutionContext *ctx = static_cast(that); @@ -279,7 +284,7 @@ void ExecutionContext::markObjects(Managed *that) ctx->thisObject.mark(); if (ctx->function) ctx->function->mark(); - for (unsigned arg = 0, lastArg = ctx->formalCount(); arg < lastArg; ++arg) + for (unsigned arg = 0, lastArg = ctx->argumentCount; arg < lastArg; ++arg) ctx->arguments[arg].mark(); for (unsigned local = 0, lastLocal = ctx->variableCount(); local < lastLocal; ++local) ctx->locals[local].mark(); @@ -595,7 +600,7 @@ void ExecutionContext::initCallContext(ExecutionEngine *engine) uint argc = argumentCount; uint valuesToAlloc = function->varCount; - bool copyArgs = function->needsActivation || argumentCount < function->formalParameterCount; + bool copyArgs = needsOwnArguments(); if (copyArgs) valuesToAlloc += qMax(argc, function->formalParameterCount); diff --git a/src/v4/qv4context.h b/src/v4/qv4context.h index 15217ba..35c586f 100644 --- a/src/v4/qv4context.h +++ b/src/v4/qv4context.h @@ -143,6 +143,8 @@ struct ExecutionContext : public Managed return Value::undefinedValue(); } + bool needsOwnArguments() const; + protected: static void destroy(Managed *that); static void markObjects(Managed *that); diff --git a/src/v4/qv4engine.cpp b/src/v4/qv4engine.cpp index 3870fd5..8664847 100644 --- a/src/v4/qv4engine.cpp +++ b/src/v4/qv4engine.cpp @@ -329,6 +329,11 @@ ExecutionContext *ExecutionEngine::popContext() if (debugger) debugger->justLeft(current); + if (!current->needsOwnArguments()) { + current->arguments = 0; + current->argumentCount = 0; + } + contextStack[contextStackPosition] = 0; current = contextStack[--contextStackPosition]; return current; -- 2.7.4