Index: src/api.cc |
diff --git a/src/api.cc b/src/api.cc |
index f2fffa2182a1be05d6dc4313c0c51f82c5bcff2a..1ed19844f9f5b7714a76cd8ffee3b98e1fcafad4 100644 |
--- a/src/api.cc |
+++ b/src/api.cc |
@@ -1651,14 +1651,104 @@ Local<Script> ScriptCompiler::CompileModule(Isolate* v8_isolate, Source* source, |
} |
+class IsIdentifierHelper { |
+ public: |
+ IsIdentifierHelper() : is_identifier_(false), first_char_(true) {} |
+ |
+ bool Check(i::String* string) { |
+ i::ConsString* cons_string = i::String::VisitFlat(this, string, 0); |
+ if (cons_string == NULL) return is_identifier_; |
+ // We don't support cons strings here. |
+ return false; |
+ } |
+ void VisitOneByteString(const uint8_t* chars, int length) { |
+ for (int i = 0; i < length; ++i) { |
+ if (first_char_) { |
+ first_char_ = false; |
+ is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]); |
+ } else { |
+ is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]); |
+ } |
+ } |
+ } |
+ void VisitTwoByteString(const uint16_t* chars, int length) { |
+ for (int i = 0; i < length; ++i) { |
+ if (first_char_) { |
+ first_char_ = false; |
+ is_identifier_ = unicode_cache_.IsIdentifierStart(chars[0]); |
+ } else { |
+ is_identifier_ &= unicode_cache_.IsIdentifierPart(chars[i]); |
+ } |
+ } |
+ } |
+ |
+ private: |
+ bool is_identifier_; |
+ bool first_char_; |
+ i::UnicodeCache unicode_cache_; |
+ DISALLOW_COPY_AND_ASSIGN(IsIdentifierHelper); |
+}; |
+ |
+ |
Local<Function> ScriptCompiler::CompileFunctionInContext( |
Isolate* v8_isolate, Source* source, Local<Context> v8_context, |
+ size_t arguments_count, Local<String> arguments[], |
size_t context_extension_count, Local<Object> context_extensions[]) { |
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate); |
ON_BAILOUT(isolate, "v8::ScriptCompiler::CompileFunctionInContext()", |
return Local<Function>()); |
LOG_API(isolate, "ScriptCompiler::CompileFunctionInContext()"); |
ENTER_V8(isolate); |
+ |
+ i::Handle<i::String> source_string; |
+ if (arguments_count) { |
+ source_string = |
+ Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "(function(")); |
+ for (size_t i = 0; i < arguments_count; ++i) { |
+ IsIdentifierHelper helper; |
+ if (!helper.Check(*Utils::OpenHandle(*arguments[i]))) { |
+ return Local<Function>(); |
+ } |
+ i::MaybeHandle<i::String> maybe_source = |
+ isolate->factory()->NewConsString(source_string, |
+ Utils::OpenHandle(*arguments[i])); |
+ if (!maybe_source.ToHandle(&source_string)) { |
+ return Local<Function>(); |
+ } |
+ if (i + 1 == arguments_count) continue; |
+ maybe_source = isolate->factory()->NewConsString( |
+ source_string, |
+ isolate->factory()->LookupSingleCharacterStringFromCode(',')); |
+ if (!maybe_source.ToHandle(&source_string)) { |
+ return Local<Function>(); |
+ } |
+ } |
+ i::Handle<i::String> brackets = |
+ Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "){")); |
+ i::MaybeHandle<i::String> maybe_source = |
+ isolate->factory()->NewConsString(source_string, brackets); |
+ if (!maybe_source.ToHandle(&source_string)) { |
+ return Local<Function>(); |
+ } |
+ } else { |
+ source_string = |
+ Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "(function(){")); |
+ } |
+ |
+ int scope_position = source_string->length(); |
+ i::MaybeHandle<i::String> maybe_source = isolate->factory()->NewConsString( |
+ source_string, Utils::OpenHandle(*source->source_string)); |
+ if (!maybe_source.ToHandle(&source_string)) { |
+ return Local<Function>(); |
+ } |
+ // Include \n in case the source contains a line end comment. |
+ i::Handle<i::String> brackets = |
+ Utils::OpenHandle(*v8::String::NewFromUtf8(v8_isolate, "\n})")); |
+ maybe_source = isolate->factory()->NewConsString(source_string, brackets); |
+ if (!maybe_source.ToHandle(&source_string)) { |
+ return Local<Function>(); |
+ } |
+ |
i::Handle<i::Context> context = Utils::OpenHandle(*v8_context); |
i::Handle<i::SharedFunctionInfo> outer_info(context->closure()->shared(), |
isolate); |
@@ -1668,13 +1758,21 @@ Local<Function> ScriptCompiler::CompileFunctionInContext( |
i::Handle<i::JSFunction> closure(context->closure(), isolate); |
context = isolate->factory()->NewWithContext(closure, context, extension); |
} |
+ |
EXCEPTION_PREAMBLE(isolate); |
- i::MaybeHandle<i::JSFunction> result = i::Compiler::GetFunctionFromEval( |
- Utils::OpenHandle(*source->source_string), outer_info, context, i::SLOPPY, |
- i::NO_PARSE_RESTRICTION, 0 /* scope_position */); |
- has_pending_exception = result.is_null(); |
+ i::MaybeHandle<i::JSFunction> maybe_fun = i::Compiler::GetFunctionFromEval( |
+ source_string, outer_info, context, i::SLOPPY, |
+ i::ONLY_SINGLE_FUNCTION_LITERAL, scope_position); |
+ i::Handle<i::JSFunction> fun; |
+ has_pending_exception = !maybe_fun.ToHandle(&fun); |
+ EXCEPTION_BAILOUT_CHECK(isolate, Local<Function>()); |
+ |
+ i::MaybeHandle<i::Object> result = i::Execution::Call( |
+ isolate, fun, Utils::OpenHandle(*v8_context->Global()), 0, NULL); |
+ i::Handle<i::Object> final_result; |
+ has_pending_exception = !result.ToHandle(&final_result); |
EXCEPTION_BAILOUT_CHECK(isolate, Local<Function>()); |
- return Utils::ToLocal(result.ToHandleChecked()); |
+ return Utils::ToLocal(i::Handle<i::JSFunction>::cast(final_result)); |
} |