| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index 031ad5a0237ac420731bd4076a74d015666036be..f59333f017cddfb497db73cfc82638541b61d58f 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -1371,6 +1371,74 @@ Local<AccessorSignature> AccessorSignature::New(
|
| return Utils::AccessorSignatureToLocal(Utils::OpenHandle(*receiver));
|
| }
|
|
|
| +Local<DictionarySchema> DictionarySchema::New(Isolate* v8_isolate,
|
| + Local<Value> keys[],
|
| + int keyCount) {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
| + LOG_API(isolate, DictionarySchema, New);
|
| + ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
|
| + i::Handle<i::DictionarySchema> schema =
|
| + i::DictionarySchema::New(isolate, keyCount);
|
| + for (int i = 0; i < keyCount; i++) {
|
| + i::Handle<i::Object> key = Utils::OpenHandle(*keys[i]);
|
| + uint32_t array_index;
|
| + Utils::ApiCheck(key->IsName() || key->ToArrayIndex(&array_index),
|
| + "v8::DictionarySchema::New",
|
| + "invalid dictionary key (must be name or array index)");
|
| + schema->set(i, *key);
|
| + }
|
| + return Utils::ToLocal(schema);
|
| +}
|
| +
|
| +Maybe<bool> DictionarySchema::Get(Local<Context> context, Local<Object> object,
|
| + ValueFilter continue_filter,
|
| + Local<Value>* out, int out_length,
|
| + int* index) {
|
| + // TODO(jbroman): This is an ugly hack.
|
| + // We could return some V8 object (v8::Array? Something else?) that must be
|
| + // queried. Or we could at least wrap this up in something that doesn't
|
| + // require us to be a friend of v8::Local.
|
| + // It's also potentially quadratic at present, if everything fails the
|
| + // continue filter.
|
| + {
|
| + i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
|
| + for (int i = *index; i < out_length; i++) {
|
| + out[i] =
|
| + Local<Value>(reinterpret_cast<Value*>(i::HandleScope::CreateHandle(
|
| + isolate, isolate->heap()->undefined_value())));
|
| + }
|
| + }
|
| +
|
| + PREPARE_FOR_EXECUTION_PRIMITIVE(context, DictionarySchema, Get, bool);
|
| + i::Handle<i::DictionarySchema> schema = Utils::OpenHandle(this);
|
| + int length = schema->length();
|
| + i::Handle<i::JSReceiver> receiver = Utils::OpenHandle(*object);
|
| + for (; *index < length; (*index)++) {
|
| + i::Handle<i::Object> key(schema->get(*index), isolate);
|
| + bool success = false;
|
| + i::LookupIterator it =
|
| + i::LookupIterator::PropertyOrElement(isolate, receiver, key, &success);
|
| + CHECK(success);
|
| + i::Handle<i::Object> value;
|
| + if (!i::Object::GetProperty(&it).ToHandle(&value)) {
|
| + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
| + }
|
| +
|
| + // TODO(jbroman): Hack to escape the handle scope.
|
| + Value* slot = out[*index].val_;
|
| + *reinterpret_cast<i::Object**>(slot) = *value;
|
| +
|
| + const bool should_pause =
|
| + (value->IsPrimitive() && !(continue_filter & kValueFilterPrimitives)) ||
|
| + (value->IsJSReceiver() && !(continue_filter & kValueFilterObjects));
|
| + if (should_pause) {
|
| + (*index)++;
|
| + return Just(false);
|
| + }
|
| + }
|
| +
|
| + return Just(true);
|
| +}
|
|
|
| #define SET_FIELD_WRAPPED(obj, setter, cdata) do { \
|
| i::Handle<i::Object> foreign = FromCData(obj->GetIsolate(), cdata); \
|
|
|