Skip to content

Instantly share code, notes, and snippets.

@jeremyroman
Created March 14, 2017 20:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeremyroman/e27111f9b1074cce59e9ab57552c8c41 to your computer and use it in GitHub Desktop.
Save jeremyroman/e27111f9b1074cce59e9ab57552c8c41 to your computer and use it in GitHub Desktop.
v8::DictionarySchema to make reading dictionaries fast
Local<DictionarySchema> DictionarySchema::New(Isolate* v8_isolate,
Local<Value> keys[],
int keyCount) {
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
i::Handle<i::DictionarySchema> schema = i::DictionarySchema::New(isolate, keyCount);
for (int i = 0; i < keyCount; i++) {
Handle<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::ToApiHandle(schema);
}
Maybe<bool> DictionarySchema::Get(Local<Context> context,
Local<Object> object,
ValueFilter continue_filter,
Local<Value>* out,
int* index) {
PREPARE_FOR_EXECUTION_PRIMITIVE(context, DictionarySchema, Get, bool);
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(context->GetIsolate());
i::Handle<i::DictionarySchema> schema = Utils::OpenHandle(this);
i::Handle<i::JSReceiver> receiver = Utils::OpenHandle(object);
for (; *index < length(); (*index)++) {
bool success = false;
i::LookupIterator it = i::LookupIterator::PropertyOrElement(isolate, receiver, keys[*index], &success);
CHECK(success);
i::Handle<i::Object> value;
if (!Object::GetProperty(&it).ToHandle(&value)) {
// blah blah blah promote exception
return Nothing<bool>();
}
out[*index] = Utils::Convert<i::Object, Value>(value);
const bool should_pause =
(value->IsPrimitive() && !(continue_filter & ValueFilter::kPrimitive)) ||
(value->IsJSReceiver() && !(continue_filter & ValueFilter::kObject));
if (should_pause) {
(*index)++;
return Just(false);
}
}
return Just(true);
}
Handle<DictionarySchema> DictionarySchema::New(Isolate* isolate, int size) {
return Handle<DictionarySchema>::cast(isolate->factory()->NewFixedArray(size, TENURED));
}
class DictionarySchema : public FixedArray {
static Handle<DictionarySchema> New(Isolate* isolate, int size);
// ...
};
class V8_EXPORT DictionarySchema : public Data {
static Local<DictionarySchema> New(Isolate* isolate,
Local<Value> keys[],
int keyCount);
enum class ValueFilter {
kPrimitive = 1 << 0,
kObject = 1 << 1,
};
/*
* Reads properties from the object according to the dictionary schema until:
* - an exception is thrown (returns Nothing), or
* - an object that doesn't match |continue_filter| is found (returns Just(false))
* - all properties are read (returns Just(true))
*/
Maybe<bool> Get(Local<Context> context,
Local<Object> object,
ValueFilter continue_filter,
Local<Value>* out
int* index);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment