From e732ac0ff496116967658e91e9fbad48e0357fcc Mon Sep 17 00:00:00 2001 From: Timothy Gu Date: Sat, 13 Jan 2018 15:37:21 -0800 Subject: [PATCH] src: factor out some common vm functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/17560 Reviewed-By: Michaƫl Zasso Reviewed-By: Tiancheng "Timothy" Gu --- src/node_contextify.cc | 447 ++++++++++++++++++++--------------------- src/node_contextify.h | 11 + 2 files changed, 233 insertions(+), 225 deletions(-) diff --git a/src/node_contextify.cc b/src/node_contextify.cc index c50cb19529c13d..35b39d62e1fc77 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -586,6 +586,227 @@ void ContextifyContext::IndexedPropertyDeleterCallback( args.GetReturnValue().Set(false); } +Maybe GetBreakOnSigintArg(Environment* env, + Local options) { + if (options->IsUndefined() || options->IsString()) { + return Just(false); + } + if (!options->IsObject()) { + env->ThrowTypeError("options must be an object"); + return Nothing(); + } + + Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "breakOnSigint"); + MaybeLocal maybe_value = + options.As()->Get(env->context(), key); + if (maybe_value.IsEmpty()) + return Nothing(); + + Local value = maybe_value.ToLocalChecked(); + return Just(value->IsTrue()); +} + +Maybe GetTimeoutArg(Environment* env, Local options) { + if (options->IsUndefined() || options->IsString()) { + return Just(-1); + } + if (!options->IsObject()) { + env->ThrowTypeError("options must be an object"); + return Nothing(); + } + + MaybeLocal maybe_value = + options.As()->Get(env->context(), env->timeout_string()); + if (maybe_value.IsEmpty()) + return Nothing(); + + Local value = maybe_value.ToLocalChecked(); + if (value->IsUndefined()) { + return Just(-1); + } + + Maybe timeout = value->IntegerValue(env->context()); + + if (timeout.IsJust() && timeout.ToChecked() <= 0) { + env->ThrowRangeError("timeout must be a positive number"); + return Nothing(); + } + + return timeout; +} + +MaybeLocal GetLineOffsetArg(Environment* env, + Local options) { + Local defaultLineOffset = Integer::New(env->isolate(), 0); + + if (!options->IsObject()) { + return defaultLineOffset; + } + + Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "lineOffset"); + MaybeLocal maybe_value = + options.As()->Get(env->context(), key); + if (maybe_value.IsEmpty()) + return MaybeLocal(); + + Local value = maybe_value.ToLocalChecked(); + if (value->IsUndefined()) + return defaultLineOffset; + + return value->ToInteger(env->context()); +} + +MaybeLocal GetColumnOffsetArg(Environment* env, + Local options) { + Local defaultColumnOffset = Integer::New(env->isolate(), 0); + + if (!options->IsObject()) { + return defaultColumnOffset; + } + + Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "columnOffset"); + MaybeLocal maybe_value = + options.As()->Get(env->context(), key); + if (maybe_value.IsEmpty()) + return MaybeLocal(); + + Local value = maybe_value.ToLocalChecked(); + if (value->IsUndefined()) + return defaultColumnOffset; + + return value->ToInteger(env->context()); +} + +MaybeLocal GetContextArg(Environment* env, + Local options) { + if (!options->IsObject()) + return MaybeLocal(); + + MaybeLocal maybe_value = + options.As()->Get(env->context(), + env->vm_parsing_context_symbol()); + Local value; + if (!maybe_value.ToLocal(&value)) + return MaybeLocal(); + + if (!value->IsObject()) { + if (!value->IsNullOrUndefined()) { + env->ThrowTypeError( + "contextifiedSandbox argument must be an object."); + } + return MaybeLocal(); + } + + ContextifyContext* sandbox = + ContextifyContext::ContextFromContextifiedSandbox( + env, value.As()); + if (!sandbox) { + env->ThrowTypeError( + "sandbox argument must have been converted to a context."); + return MaybeLocal(); + } + + Local context = sandbox->context(); + if (context.IsEmpty()) + return MaybeLocal(); + return context; +} + +namespace { + +Maybe GetDisplayErrorsArg(Environment* env, + Local options) { + if (options->IsUndefined() || options->IsString()) { + return Just(true); + } + if (!options->IsObject()) { + env->ThrowTypeError("options must be an object"); + return Nothing(); + } + + Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "displayErrors"); + MaybeLocal maybe_value = + options.As()->Get(env->context(), key); + if (maybe_value.IsEmpty()) + return Nothing(); + + Local value = maybe_value.ToLocalChecked(); + if (value->IsUndefined()) + return Just(true); + + return value->BooleanValue(env->context()); +} + +MaybeLocal GetFilenameArg(Environment* env, + Local options) { + Local defaultFilename = + FIXED_ONE_BYTE_STRING(env->isolate(), "evalmachine."); + + if (options->IsUndefined()) { + return defaultFilename; + } + if (options->IsString()) { + return options.As(); + } + if (!options->IsObject()) { + env->ThrowTypeError("options must be an object"); + return Local(); + } + + Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "filename"); + MaybeLocal maybe_value = + options.As()->Get(env->context(), key); + if (maybe_value.IsEmpty()) + return MaybeLocal(); + + Local value = maybe_value.ToLocalChecked(); + if (value->IsUndefined()) + return defaultFilename; + return value->ToString(env->context()); +} + +MaybeLocal GetCachedData(Environment* env, + Local options) { + if (!options->IsObject()) { + return MaybeLocal(); + } + + MaybeLocal maybe_value = + options.As()->Get(env->context(), env->cached_data_string()); + if (maybe_value.IsEmpty()) + return MaybeLocal(); + + Local value = maybe_value.ToLocalChecked(); + if (value->IsUndefined()) { + return MaybeLocal(); + } + + if (!value->IsUint8Array()) { + env->ThrowTypeError("options.cachedData must be a Buffer instance"); + return MaybeLocal(); + } + + return value.As(); +} + +Maybe GetProduceCachedData(Environment* env, + Local options) { + if (!options->IsObject()) { + return Just(false); + } + + MaybeLocal maybe_value = + options.As()->Get(env->context(), + env->produce_cached_data_string()); + if (maybe_value.IsEmpty()) + return Nothing(); + + Local value = maybe_value.ToLocalChecked(); + return Just(value->IsTrue()); +} + +} // anonymous namespace + class ContextifyScript : public BaseObject { private: Persistent script_; @@ -639,7 +860,7 @@ class ContextifyScript : public BaseObject { MaybeLocal columnOffset = GetColumnOffsetArg(env, options); MaybeLocal cached_data_buf = GetCachedData(env, options); Maybe maybe_produce_cached_data = GetProduceCachedData(env, options); - MaybeLocal maybe_context = GetContext(env, options); + MaybeLocal maybe_context = GetContextArg(env, options); if (try_catch.HasCaught()) { no_abort_scope.Close(); try_catch.ReThrow(); @@ -831,230 +1052,6 @@ class ContextifyScript : public BaseObject { True(env->isolate())); } - static Maybe GetBreakOnSigintArg(Environment* env, - Local options) { - if (options->IsUndefined() || options->IsString()) { - return Just(false); - } - if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); - return Nothing(); - } - - Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "breakOnSigint"); - MaybeLocal maybe_value = - options.As()->Get(env->context(), key); - if (maybe_value.IsEmpty()) - return Nothing(); - - Local value = maybe_value.ToLocalChecked(); - return Just(value->IsTrue()); - } - - static Maybe GetTimeoutArg(Environment* env, Local options) { - if (options->IsUndefined() || options->IsString()) { - return Just(-1); - } - if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); - return Nothing(); - } - - MaybeLocal maybe_value = - options.As()->Get(env->context(), env->timeout_string()); - if (maybe_value.IsEmpty()) - return Nothing(); - - Local value = maybe_value.ToLocalChecked(); - if (value->IsUndefined()) { - return Just(-1); - } - - Maybe timeout = value->IntegerValue(env->context()); - - if (timeout.IsJust() && timeout.ToChecked() <= 0) { - env->ThrowRangeError("timeout must be a positive number"); - return Nothing(); - } - - return timeout; - } - - - static Maybe GetDisplayErrorsArg(Environment* env, - Local options) { - if (options->IsUndefined() || options->IsString()) { - return Just(true); - } - if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); - return Nothing(); - } - - Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "displayErrors"); - MaybeLocal maybe_value = - options.As()->Get(env->context(), key); - if (maybe_value.IsEmpty()) - return Nothing(); - - Local value = maybe_value.ToLocalChecked(); - if (value->IsUndefined()) - return Just(true); - - return value->BooleanValue(env->context()); - } - - - static MaybeLocal GetFilenameArg(Environment* env, - Local options) { - Local defaultFilename = - FIXED_ONE_BYTE_STRING(env->isolate(), "evalmachine."); - - if (options->IsUndefined()) { - return defaultFilename; - } - if (options->IsString()) { - return options.As(); - } - if (!options->IsObject()) { - env->ThrowTypeError("options must be an object"); - return Local(); - } - - Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "filename"); - MaybeLocal maybe_value = - options.As()->Get(env->context(), key); - if (maybe_value.IsEmpty()) - return MaybeLocal(); - - Local value = maybe_value.ToLocalChecked(); - if (value->IsUndefined()) - return defaultFilename; - return value->ToString(env->context()); - } - - - static MaybeLocal GetCachedData(Environment* env, - Local options) { - if (!options->IsObject()) { - return MaybeLocal(); - } - - MaybeLocal maybe_value = - options.As()->Get(env->context(), env->cached_data_string()); - if (maybe_value.IsEmpty()) - return MaybeLocal(); - - Local value = maybe_value.ToLocalChecked(); - if (value->IsUndefined()) { - return MaybeLocal(); - } - - if (!value->IsUint8Array()) { - env->ThrowTypeError("options.cachedData must be a Buffer instance"); - return MaybeLocal(); - } - - return value.As(); - } - - - static Maybe GetProduceCachedData(Environment* env, - Local options) { - if (!options->IsObject()) { - return Just(false); - } - - MaybeLocal maybe_value = - options.As()->Get(env->context(), - env->produce_cached_data_string()); - if (maybe_value.IsEmpty()) - return Nothing(); - - Local value = maybe_value.ToLocalChecked(); - return Just(value->IsTrue()); - } - - - static MaybeLocal GetLineOffsetArg(Environment* env, - Local options) { - Local defaultLineOffset = Integer::New(env->isolate(), 0); - - if (!options->IsObject()) { - return defaultLineOffset; - } - - Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "lineOffset"); - MaybeLocal maybe_value = - options.As()->Get(env->context(), key); - if (maybe_value.IsEmpty()) - return MaybeLocal(); - - Local value = maybe_value.ToLocalChecked(); - if (value->IsUndefined()) - return defaultLineOffset; - - return value->ToInteger(env->context()); - } - - - static MaybeLocal GetColumnOffsetArg(Environment* env, - Local options) { - Local defaultColumnOffset = Integer::New(env->isolate(), 0); - - if (!options->IsObject()) { - return defaultColumnOffset; - } - - Local key = FIXED_ONE_BYTE_STRING(env->isolate(), "columnOffset"); - MaybeLocal maybe_value = - options.As()->Get(env->context(), key); - if (maybe_value.IsEmpty()) - return MaybeLocal(); - - Local value = maybe_value.ToLocalChecked(); - if (value->IsUndefined()) - return defaultColumnOffset; - - return value->ToInteger(env->context()); - } - - static MaybeLocal GetContext(Environment* env, - Local options) { - if (!options->IsObject()) - return MaybeLocal(); - - MaybeLocal maybe_value = - options.As()->Get(env->context(), - env->vm_parsing_context_symbol()); - Local value; - if (!maybe_value.ToLocal(&value)) - return MaybeLocal(); - - if (!value->IsObject()) { - if (!value->IsNullOrUndefined()) { - env->ThrowTypeError( - "contextifiedSandbox argument must be an object."); - } - return MaybeLocal(); - } - - ContextifyContext* sandbox = - ContextifyContext::ContextFromContextifiedSandbox( - env, value.As()); - if (!sandbox) { - env->ThrowTypeError( - "sandbox argument must have been converted to a context."); - return MaybeLocal(); - } - - Local context = sandbox->context(); - if (context.IsEmpty()) - return MaybeLocal(); - return context; - } - - static bool EvalMachine(Environment* env, const int64_t timeout, const bool display_errors, diff --git a/src/node_contextify.h b/src/node_contextify.h index e8a54e1667cc31..b2f32850ac1c43 100644 --- a/src/node_contextify.h +++ b/src/node_contextify.h @@ -92,6 +92,17 @@ class ContextifyContext { const v8::PropertyCallbackInfo& args); }; +v8::Maybe GetBreakOnSigintArg( + Environment* env, v8::Local options); +v8::Maybe GetTimeoutArg( + Environment* env, v8::Local options); +v8::MaybeLocal GetLineOffsetArg( + Environment* env, v8::Local options); +v8::MaybeLocal GetColumnOffsetArg( + Environment* env, v8::Local options); +v8::MaybeLocal GetContextArg( + Environment* env, v8::Local options); + } // namespace contextify } // namespace node