Index: src/json-parser.cc |
diff --git a/src/json-parser.cc b/src/json-parser.cc |
index fc8b17943b8aa03f458b5ee82dc335552c8a96fb..e1a342150cbad0e5a7103d896478d3b2f47cc683 100644 |
--- a/src/json-parser.cc |
+++ b/src/json-parser.cc |
@@ -13,16 +13,96 @@ |
#include "src/objects-inl.h" |
#include "src/parsing/scanner.h" |
#include "src/parsing/token.h" |
+#include "src/property-descriptor.h" |
#include "src/transitions.h" |
namespace v8 { |
namespace internal { |
+MaybeHandle<Object> JsonParseInternalizer::Internalize(Isolate* isolate, |
+ Handle<Object> object, |
+ Handle<Object> reviver) { |
+ DCHECK(reviver->IsCallable()); |
+ JsonParseInternalizer internalizer(isolate, |
+ Handle<JSReceiver>::cast(reviver)); |
+ Handle<JSObject> holder = |
+ isolate->factory()->NewJSObject(isolate->object_function()); |
+ Handle<String> name = isolate->factory()->empty_string(); |
+ JSObject::AddProperty(holder, name, object, NONE); |
+ return internalizer.InternalizeJsonProperty(holder, name); |
+} |
+ |
+MaybeHandle<Object> JsonParseInternalizer::InternalizeJsonProperty( |
+ Handle<JSReceiver> holder, Handle<String> name) { |
+ HandleScope outer_scope(isolate_); |
+ Handle<Object> value; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate_, value, Object::GetPropertyOrElement(holder, name), Object); |
+ if (value->IsJSReceiver()) { |
+ Handle<JSReceiver> object = Handle<JSReceiver>::cast(value); |
+ Maybe<bool> is_array = Object::IsArray(object); |
+ if (is_array.IsNothing()) return MaybeHandle<Object>(); |
+ if (is_array.FromJust()) { |
+ Handle<Object> length_object; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate_, length_object, |
+ Object::GetLengthFromArrayLike(isolate_, object), Object); |
+ double length = length_object->Number(); |
+ for (double i = 0; i < length; i++) { |
+ HandleScope inner_scope(isolate_); |
+ Handle<Object> index = isolate_->factory()->NewNumber(i); |
+ Handle<String> name = isolate_->factory()->NumberToString(index); |
+ if (!RecurseAndApply(object, name)) return MaybeHandle<Object>(); |
+ } |
+ } else { |
+ Handle<FixedArray> contents; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate_, contents, |
+ KeyAccumulator::GetKeys(object, KeyCollectionMode::kOwnOnly, |
+ ENUMERABLE_STRINGS, |
+ GetKeysConversion::kConvertToString), |
+ Object); |
+ for (int i = 0; i < contents->length(); i++) { |
+ HandleScope inner_scope(isolate_); |
+ Handle<String> name(String::cast(contents->get(i)), isolate_); |
+ if (!RecurseAndApply(object, name)) return MaybeHandle<Object>(); |
+ } |
+ } |
+ } |
+ Handle<Object> argv[] = {name, value}; |
+ Handle<Object> result; |
+ ASSIGN_RETURN_ON_EXCEPTION( |
+ isolate_, result, Execution::Call(isolate_, reviver_, holder, 2, argv), |
+ Object); |
+ return outer_scope.CloseAndEscape(result); |
+} |
+ |
+bool JsonParseInternalizer::RecurseAndApply(Handle<JSReceiver> holder, |
+ Handle<String> name) { |
+ Handle<Object> result; |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
+ isolate_, result, InternalizeJsonProperty(holder, name), false); |
+ Maybe<bool> change_result = Nothing<bool>(); |
+ if (result->IsUndefined()) { |
+ change_result = JSReceiver::DeletePropertyOrElement(holder, name, SLOPPY); |
+ } else { |
+ PropertyDescriptor desc; |
+ desc.set_value(result); |
+ desc.set_configurable(true); |
+ desc.set_enumerable(true); |
+ desc.set_writable(true); |
+ change_result = JSReceiver::DefineOwnProperty(isolate_, holder, name, &desc, |
+ Object::DONT_THROW); |
+ } |
+ MAYBE_RETURN(change_result, false); |
+ return true; |
+} |
+ |
template <bool seq_one_byte> |
-JsonParser<seq_one_byte>::JsonParser(Handle<String> source) |
+JsonParser<seq_one_byte>::JsonParser(Isolate* isolate, Handle<String> source) |
: source_(source), |
source_length_(source->length()), |
- isolate_(source->map()->GetHeap()->isolate()), |
+ isolate_(isolate), |
factory_(isolate_->factory()), |
zone_(isolate_->allocator()), |
object_constructor_(isolate_->native_context()->object_function(), |
@@ -90,6 +170,9 @@ MaybeHandle<Object> JsonParser<seq_one_byte>::ParseJson() { |
return result; |
} |
+MaybeHandle<Object> InternalizeJsonProperty(Handle<JSObject> holder, |
+ Handle<String> key); |
+ |
template <bool seq_one_byte> |
void JsonParser<seq_one_byte>::Advance() { |
position_++; |