Revision: 6729
Author: [email protected]
Date: Thu Feb 10 06:41:16 2011
Log: Fix various places which do not check if SetProperty threw an
exception.
Review URL: http://codereview.chromium.org/6480003
http://code.google.com/p/v8/source/detail?r=6729
Modified:
/branches/bleeding_edge/src/api.cc
/branches/bleeding_edge/src/bootstrapper.cc
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/factory.cc
/branches/bleeding_edge/src/handles.cc
/branches/bleeding_edge/src/handles.h
/branches/bleeding_edge/src/runtime.cc
/branches/bleeding_edge/src/top.cc
/branches/bleeding_edge/src/top.h
=======================================
--- /branches/bleeding_edge/src/api.cc Thu Feb 10 06:09:52 2011
+++ /branches/bleeding_edge/src/api.cc Thu Feb 10 06:41:16 2011
@@ -670,7 +670,7 @@
void Template::Set(v8::Handle<String> name, v8::Handle<Data> value,
v8::PropertyAttribute attribute) {
- if (IsDeadCheck("v8::Template::SetProperty()")) return;
+ if (IsDeadCheck("v8::Template::Set()")) return;
ENTER_V8;
HandleScope scope;
i::Handle<i::Object> list(Utils::OpenHandle(this)->property_list());
=======================================
--- /branches/bleeding_edge/src/bootstrapper.cc Wed Feb 2 05:31:52 2011
+++ /branches/bleeding_edge/src/bootstrapper.cc Thu Feb 10 06:41:16 2011
@@ -349,7 +349,7 @@
prototype,
call_code,
is_ecma_native);
- SetProperty(target, symbol, function, DONT_ENUM);
+ SetLocalPropertyNoThrow(target, symbol, function, DONT_ENUM);
if (is_ecma_native) {
function->shared()->set_instance_class_name(*symbol);
}
@@ -580,8 +580,8 @@
Handle<JSObject> prototype =
Handle<JSObject>(
JSObject::cast(js_global_function->instance_prototype()));
- SetProperty(prototype, Factory::constructor_symbol(),
- Top::object_function(), NONE);
+ SetLocalPropertyNoThrow(
+ prototype, Factory::constructor_symbol(), Top::object_function(),
NONE);
} else {
Handle<FunctionTemplateInfo> js_global_constructor(
FunctionTemplateInfo::cast(js_global_template->constructor()));
@@ -683,7 +683,8 @@
global_context()->set_security_token(*inner_global);
Handle<String> object_name = Handle<String>(Heap::Object_symbol());
- SetProperty(inner_global, object_name, Top::object_function(),
DONT_ENUM);
+ SetLocalPropertyNoThrow(inner_global, object_name,
+ Top::object_function(), DONT_ENUM);
Handle<JSObject> global = Handle<JSObject>(global_context()->global());
@@ -851,7 +852,7 @@
cons->SetInstanceClassName(*name);
Handle<JSObject> json_object = Factory::NewJSObject(cons, TENURED);
ASSERT(json_object->IsJSObject());
- SetProperty(global, name, json_object, DONT_ENUM);
+ SetLocalPropertyNoThrow(global, name, json_object, DONT_ENUM);
global_context()->set_json_object(*json_object);
}
@@ -880,12 +881,12 @@
global_context()->set_arguments_boilerplate(*result);
// Note: callee must be added as the first property and
// length must be added as the second property.
- SetProperty(result, Factory::callee_symbol(),
- Factory::undefined_value(),
- DONT_ENUM);
- SetProperty(result, Factory::length_symbol(),
- Factory::undefined_value(),
- DONT_ENUM);
+ SetLocalPropertyNoThrow(result, Factory::callee_symbol(),
+ Factory::undefined_value(),
+ DONT_ENUM);
+ SetLocalPropertyNoThrow(result, Factory::length_symbol(),
+ Factory::undefined_value(),
+ DONT_ENUM);
#ifdef DEBUG
LookupResult lookup;
@@ -1085,10 +1086,8 @@
static const PropertyAttributes attributes =
static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE);
Handle<String> global_symbol = Factory::LookupAsciiSymbol("global");
- SetProperty(builtins,
- global_symbol,
- Handle<Object>(global_context()->global()),
- attributes);
+ Handle<Object> global_obj(global_context()->global());
+ SetLocalPropertyNoThrow(builtins, global_symbol, global_obj, attributes);
// Setup the reference from the global object to the builtins object.
JSGlobalObject::cast(global_context()->global())->set_builtins(*builtins);
@@ -1480,17 +1479,17 @@
if (FLAG_expose_natives_as != NULL && strlen(FLAG_expose_natives_as) !=
0) {
Handle<String> natives_string =
Factory::LookupAsciiSymbol(FLAG_expose_natives_as);
- SetProperty(js_global, natives_string,
- Handle<JSObject>(js_global->builtins()), DONT_ENUM);
+ SetLocalPropertyNoThrow(js_global, natives_string,
+ Handle<JSObject>(js_global->builtins()),
DONT_ENUM);
}
Handle<Object> Error = GetProperty(js_global, "Error");
if (Error->IsJSObject()) {
Handle<String> name = Factory::LookupAsciiSymbol("stackTraceLimit");
- SetProperty(Handle<JSObject>::cast(Error),
- name,
- Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
- NONE);
+ SetLocalPropertyNoThrow(Handle<JSObject>::cast(Error),
+ name,
+
Handle<Smi>(Smi::FromInt(FLAG_stack_trace_limit)),
+ NONE);
}
#ifdef ENABLE_DEBUGGER_SUPPORT
@@ -1507,8 +1506,8 @@
Handle<String> debug_string =
Factory::LookupAsciiSymbol(FLAG_expose_debug_as);
- SetProperty(js_global, debug_string,
- Handle<Object>(Debug::debug_context()->global_proxy()), DONT_ENUM);
+ Handle<Object> global_proxy(Debug::debug_context()->global_proxy());
+ SetLocalPropertyNoThrow(js_global, debug_string, global_proxy,
DONT_ENUM);
}
#endif
}
@@ -1679,7 +1678,7 @@
Handle<String> key = Handle<String>(descs->GetKey(i));
int index = descs->GetFieldIndex(i);
Handle<Object> value =
Handle<Object>(from->FastPropertyAt(index));
- SetProperty(to, key, value, details.attributes());
+ SetLocalPropertyNoThrow(to, key, value, details.attributes());
break;
}
case CONSTANT_FUNCTION: {
@@ -1687,7 +1686,7 @@
Handle<String> key = Handle<String>(descs->GetKey(i));
Handle<JSFunction> fun =
Handle<JSFunction>(descs->GetConstantFunction(i));
- SetProperty(to, key, fun, details.attributes());
+ SetLocalPropertyNoThrow(to, key, fun, details.attributes());
break;
}
case CALLBACKS: {
@@ -1737,7 +1736,7 @@
value =
Handle<Object>(JSGlobalPropertyCell::cast(*value)->value());
}
PropertyDetails details = properties->DetailsAt(i);
- SetProperty(to, key, value, details.attributes());
+ SetLocalPropertyNoThrow(to, key, value, details.attributes());
}
}
}
=======================================
--- /branches/bleeding_edge/src/debug.cc Thu Jan 6 05:14:32 2011
+++ /branches/bleeding_edge/src/debug.cc Thu Feb 10 06:41:16 2011
@@ -835,7 +835,9 @@
// Expose the builtins object in the debugger context.
Handle<String> key = Factory::LookupAsciiSymbol("builtins");
Handle<GlobalObject> global = Handle<GlobalObject>(context->global());
- SetProperty(global, key, Handle<Object>(global->builtins()), NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(global, key, Handle<Object>(global->builtins()), NONE),
+ false);
// Compile the JavaScript for the debugger in the debugger context.
Debugger::set_compiling_natives(true);
=======================================
--- /branches/bleeding_edge/src/factory.cc Thu Feb 10 04:02:36 2011
+++ /branches/bleeding_edge/src/factory.cc Thu Feb 10 06:41:16 2011
@@ -585,7 +585,9 @@
// Set function.prototype and give the prototype a constructor
// property that refers to the function.
SetPrototypeProperty(function, prototype);
- SetProperty(prototype, Factory::constructor_symbol(), function,
DONT_ENUM);
+ // Currently safe because it is only invoked from Genesis.
+ SetLocalPropertyNoThrow(
+ prototype, Factory::constructor_symbol(), function, DONT_ENUM);
return function;
}
=======================================
--- /branches/bleeding_edge/src/handles.cc Tue Feb 8 11:42:14 2011
+++ /branches/bleeding_edge/src/handles.cc Thu Feb 10 06:41:16 2011
@@ -288,6 +288,17 @@
CALL_HEAP_FUNCTION(object->
SetLocalPropertyIgnoreAttributes(*key, *value, attributes), Object);
}
+
+
+void SetLocalPropertyNoThrow(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes) {
+ ASSERT(!Top::has_pending_exception());
+ CHECK(!SetLocalPropertyIgnoreAttributes(
+ object, key, value, attributes).is_null());
+ CHECK(!Top::has_pending_exception());
+}
Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
=======================================
--- /branches/bleeding_edge/src/handles.h Thu Jan 6 06:00:50 2011
+++ /branches/bleeding_edge/src/handles.h Thu Feb 10 06:41:16 2011
@@ -223,6 +223,13 @@
Handle<Object> value,
PropertyAttributes attributes);
+// Used to set local properties on the object we totally control
+// and which therefore has no accessors and alikes.
+void SetLocalPropertyNoThrow(Handle<JSObject> object,
+ Handle<String> key,
+ Handle<Object> value,
+ PropertyAttributes attributes = NONE);
+
Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object,
Handle<String> key,
Handle<Object> value,
=======================================
--- /branches/bleeding_edge/src/runtime.cc Wed Feb 9 03:38:10 2011
+++ /branches/bleeding_edge/src/runtime.cc Thu Feb 10 06:41:16 2011
@@ -1089,11 +1089,7 @@
const char* type = (lookup.IsReadOnly()) ? "const" : "var";
return ThrowRedeclarationError(type, name);
}
- Handle<Object> result = SetProperty(global, name, value, attributes);
- if (result.is_null()) {
- ASSERT(Top::has_pending_exception());
- return Failure::Exception();
- }
+ RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, attributes));
} else {
// If a property with this name does not already exist on the
// global object add the property locally. We take special
@@ -1101,12 +1097,8 @@
// of callbacks in the prototype chain (this rules out using
// SetProperty). Also, we must use the handle-based version to
// avoid GC issues.
- Handle<Object> result =
- SetLocalPropertyIgnoreAttributes(global, name, value,
attributes);
- if (result.is_null()) {
- ASSERT(Top::has_pending_exception());
- return Failure::Exception();
- }
+ RETURN_IF_EMPTY_HANDLE(
+ SetLocalPropertyIgnoreAttributes(global, name, value,
attributes));
}
}
@@ -1166,9 +1158,8 @@
} else {
// Slow case: The property is not in the FixedArray part of the
context.
Handle<JSObject> context_ext = Handle<JSObject>::cast(holder);
- Handle<Object> result =
- SetProperty(context_ext, name, initial_value, mode);
- if (result.is_null()) return Failure::Exception();
+ RETURN_IF_EMPTY_HANDLE(
+ SetProperty(context_ext, name, initial_value, mode));
}
}
@@ -1195,8 +1186,7 @@
ASSERT(!context_ext->HasLocalProperty(*name));
Handle<Object> value(Heap::undefined_value());
if (*initial_value != NULL) value = initial_value;
- Handle<Object> result = SetProperty(context_ext, name, value, mode);
- if (result.is_null()) return Failure::Exception();
+ RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, mode));
}
return Heap::undefined_value();
@@ -1345,12 +1335,12 @@
// with setting the value because the property is either absent or
// read-only. We also have to do redo the lookup.
HandleScope handle_scope;
- Handle<GlobalObject>global(Top::context()->global());
-
- // BUG 1213579: Handle the case where we have to set a read-only
+ Handle<GlobalObject> global(Top::context()->global());
+
+ // BUG 1213575: Handle the case where we have to set a read-only
// property through an interceptor and only do it if it's
// uninitialized, e.g. the hole. Nirk...
- SetProperty(global, name, value, attributes);
+ RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, attributes));
return *value;
}
@@ -1432,7 +1422,7 @@
// context.
if (attributes == ABSENT) {
Handle<JSObject> global = Handle<JSObject>(Top::context()->global());
- SetProperty(global, name, value, NONE);
+ RETURN_IF_EMPTY_HANDLE(SetProperty(global, name, value, NONE));
return *value;
}
@@ -1469,14 +1459,8 @@
// The property was found in a different context extension object.
// Set it if it is not a read-only property.
if ((attributes & READ_ONLY) == 0) {
- Handle<Object> set = SetProperty(context_ext, name, value,
attributes);
- // Setting a property might throw an exception. Exceptions
- // are converted to empty handles in handle operations. We
- // need to convert back to exceptions here.
- if (set.is_null()) {
- ASSERT(Top::has_pending_exception());
- return Failure::Exception();
- }
+ RETURN_IF_EMPTY_HANDLE(
+ SetProperty(context_ext, name, value, attributes));
}
}
@@ -7424,14 +7408,7 @@
// extension object itself.
if ((attributes & READ_ONLY) == 0 ||
(context_ext->GetLocalPropertyAttribute(*name) == ABSENT)) {
- Handle<Object> result = SetProperty(context_ext, name, value, NONE);
- if (result.is_null()) {
- // Failure::Exception is converted to a null handle in the
- // handle-based methods such as SetProperty. We therefore need
- // to convert null handles back to exceptions.
- ASSERT(Top::has_pending_exception());
- return Failure::Exception();
- }
+ RETURN_IF_EMPTY_HANDLE(SetProperty(context_ext, name, value, NONE));
}
return *value;
}
@@ -9075,7 +9052,7 @@
// Copy all the context locals into an object used to materialize a scope.
-static void CopyContextLocalsToScopeObject(
+static bool CopyContextLocalsToScopeObject(
Handle<SerializedScopeInfo> serialized_scope_info,
ScopeInfo<>& scope_info,
Handle<Context> context,
@@ -9089,11 +9066,15 @@
// Don't include the arguments shadow (.arguments) context variable.
if (*scope_info.context_slot_name(i) !=
Heap::arguments_shadow_symbol()) {
- SetProperty(scope_object,
- scope_info.context_slot_name(i),
- Handle<Object>(context->get(context_index)), NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(scope_object,
+ scope_info.context_slot_name(i),
+ Handle<Object>(context->get(context_index)), NONE),
+ false);
}
}
+
+ return true;
}
@@ -9111,23 +9092,29 @@
// First fill all parameters.
for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
- SetProperty(local_scope,
- scope_info.parameter_name(i),
- Handle<Object>(frame->GetParameter(i)), NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(local_scope,
+ scope_info.parameter_name(i),
+ Handle<Object>(frame->GetParameter(i)), NONE),
+ Handle<JSObject>());
}
// Second fill all stack locals.
for (int i = 0; i < scope_info.number_of_stack_slots(); i++) {
- SetProperty(local_scope,
- scope_info.stack_slot_name(i),
- Handle<Object>(frame->GetExpression(i)), NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(local_scope,
+ scope_info.stack_slot_name(i),
+ Handle<Object>(frame->GetExpression(i)), NONE),
+ Handle<JSObject>());
}
// Third fill all context locals.
Handle<Context> frame_context(Context::cast(frame->context()));
Handle<Context> function_context(frame_context->fcontext());
- CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
- function_context, local_scope);
+ if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
+ function_context, local_scope)) {
+ return Handle<JSObject>();
+ }
// Finally copy any properties from the function context extension. This
will
// be variables introduced by eval.
@@ -9140,7 +9127,9 @@
// Names of variables introduced by eval are strings.
ASSERT(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
- SetProperty(local_scope, key, GetProperty(ext, key), NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(local_scope, key, GetProperty(ext, key), NONE),
+ Handle<JSObject>());
}
}
}
@@ -9173,16 +9162,20 @@
for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
// We don't expect exception-throwing getters on the arguments
shadow.
Object* element =
arguments_shadow->GetElement(i)->ToObjectUnchecked();
- SetProperty(closure_scope,
- scope_info.parameter_name(i),
- Handle<Object>(element),
- NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(closure_scope,
+ scope_info.parameter_name(i),
+ Handle<Object>(element),
+ NONE),
+ Handle<JSObject>());
}
}
// Fill all context locals to the context extension.
- CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
- context, closure_scope);
+ if (!CopyContextLocalsToScopeObject(serialized_scope_info, scope_info,
+ context, closure_scope)) {
+ return Handle<JSObject>();
+ }
// Finally copy any properties from the function context extension. This
will
// be variables introduced by eval.
@@ -9193,7 +9186,9 @@
// Names of variables introduced by eval are strings.
ASSERT(keys->get(i)->IsString());
Handle<String> key(String::cast(keys->get(i)));
- SetProperty(closure_scope, key, GetProperty(ext, key), NONE);
+ RETURN_IF_EMPTY_HANDLE_VALUE(
+ SetProperty(closure_scope, key, GetProperty(ext, key), NONE),
+ Handle<JSObject>());
}
}
@@ -9480,6 +9475,7 @@
// Fill in scope details.
details->set(kScopeDetailsTypeIndex, Smi::FromInt(it.Type()));
Handle<JSObject> scope_object = it.ScopeObject();
+ RETURN_IF_EMPTY_HANDLE(scope_object);
details->set(kScopeDetailsObjectIndex, *scope_object);
return *Factory::NewJSArrayWithElements(details);
@@ -9961,6 +9957,7 @@
// Materialize the content of the local scope into a JSObject.
Handle<JSObject> local_scope = MaterializeLocalScope(frame);
+ RETURN_IF_EMPTY_HANDLE(local_scope);
// Allocate a new context for the debug evaluation and set the extension
// object build.
=======================================
--- /branches/bleeding_edge/src/top.cc Wed Feb 9 11:34:04 2011
+++ /branches/bleeding_edge/src/top.cc Thu Feb 10 06:41:16 2011
@@ -372,18 +372,6 @@
return Factory::empty_symbol();
}
}
-
-
-static void SetLocalProperty(Handle<JSObject> object,
- Handle<String> key,
- Handle<Object> value) {
- // We set properties on freshly allocated JS object, nothing
- // should fail except for OOM which is handled by
- // SetLocalPropertyIgnoreAttributes.
- ASSERT(!Top::has_pending_exception());
- CHECK(!SetLocalPropertyIgnoreAttributes(object, key, value,
NONE).is_null());
- CHECK(!Top::has_pending_exception());
-}
Handle<JSArray> Top::CaptureCurrentStackTrace(
@@ -433,16 +421,16 @@
// tag.
column_offset += script->column_offset()->value();
}
- SetLocalProperty(stackFrame, column_key,
- Handle<Smi>(Smi::FromInt(column_offset + 1)));
- }
- SetLocalProperty(stackFrame, line_key,
- Handle<Smi>(Smi::FromInt(line_number + 1)));
+ SetLocalPropertyNoThrow(stackFrame, column_key,
+ Handle<Smi>(Smi::FromInt(column_offset +
1)));
+ }
+ SetLocalPropertyNoThrow(stackFrame, line_key,
+ Handle<Smi>(Smi::FromInt(line_number +
1)));
}
if (options & StackTrace::kScriptName) {
Handle<Object> script_name(script->name());
- SetLocalProperty(stackFrame, script_key, script_name);
+ SetLocalPropertyNoThrow(stackFrame, script_key, script_name);
}
if (options & StackTrace::kScriptNameOrSourceURL) {
@@ -458,7 +446,8 @@
if (caught_exception) {
result = Factory::undefined_value();
}
- SetLocalProperty(stackFrame, script_name_or_source_url_key,
result);
+ SetLocalPropertyNoThrow(stackFrame, script_name_or_source_url_key,
+ result);
}
if (options & StackTrace::kFunctionName) {
@@ -466,20 +455,20 @@
if (fun_name->ToBoolean()->IsFalse()) {
fun_name = Handle<Object>(fun->shared()->inferred_name());
}
- SetLocalProperty(stackFrame, function_key, fun_name);
+ SetLocalPropertyNoThrow(stackFrame, function_key, fun_name);
}
if (options & StackTrace::kIsEval) {
int type = Smi::cast(script->compilation_type())->value();
Handle<Object> is_eval = (type == Script::COMPILATION_TYPE_EVAL) ?
Factory::true_value() : Factory::false_value();
- SetLocalProperty(stackFrame, eval_key, is_eval);
+ SetLocalPropertyNoThrow(stackFrame, eval_key, is_eval);
}
if (options & StackTrace::kIsConstructor) {
Handle<Object> is_constructor = (frames[i].is_constructor()) ?
Factory::true_value() : Factory::false_value();
- SetLocalProperty(stackFrame, constructor_key, is_constructor);
+ SetLocalPropertyNoThrow(stackFrame, constructor_key,
is_constructor);
}
FixedArray::cast(stack_trace->elements())->set(frames_seen,
*stackFrame);
=======================================
--- /branches/bleeding_edge/src/top.h Fri Feb 4 05:43:38 2011
+++ /branches/bleeding_edge/src/top.h Thu Feb 10 06:41:16 2011
@@ -41,6 +41,15 @@
#define RETURN_IF_SCHEDULED_EXCEPTION() \
if (Top::has_scheduled_exception()) return
Top::PromoteScheduledException()
+#define RETURN_IF_EMPTY_HANDLE_VALUE(call, value) \
+ if (call.is_null()) { \
+ ASSERT(Top::has_pending_exception()); \
+ return value; \
+ }
+
+#define RETURN_IF_EMPTY_HANDLE(call) \
+ RETURN_IF_EMPTY_HANDLE_VALUE(call, Failure::Exception())
+
// Top has static variables used for JavaScript execution.
class SaveContext; // Forward declaration.
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev