| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright 2013 Google Inc. |    2  * Copyright 2013 Google Inc. | 
|    3  * |    3  * | 
|    4  * |    4  * | 
|    5  * Use of this source code is governed by a BSD-style license that can be |    5  * Use of this source code is governed by a BSD-style license that can be | 
|    6  * found in the LICENSE file. |    6  * found in the LICENSE file. | 
|    7  * |    7  * | 
|    8  */ |    8  */ | 
|    9 #include "Global.h" |    9 #include "Global.h" | 
|   10  |   10  | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
|   23     do { |   23     do { | 
|   24         fLastTimerID++; |   24         fLastTimerID++; | 
|   25         if (fLastTimerID < 0) { |   25         if (fLastTimerID < 0) { | 
|   26             fLastTimerID = 0; |   26             fLastTimerID = 0; | 
|   27         } |   27         } | 
|   28     } while (fTimeouts.find(fLastTimerID) != fTimeouts.end()); |   28     } while (fTimeouts.find(fLastTimerID) != fTimeouts.end()); | 
|   29     return fLastTimerID; |   29     return fLastTimerID; | 
|   30 } |   30 } | 
|   31  |   31  | 
|   32 // Slight modification to an original function found in the V8 sample shell.cc. |   32 // Slight modification to an original function found in the V8 sample shell.cc. | 
|   33 void Global::reportException(TryCatch* tryCatch) { |   33 void Global::reportException(v8::TryCatch* tryCatch) { | 
|   34     HandleScope handleScope(fIsolate); |   34     v8::HandleScope handleScope(fIsolate); | 
|   35     String::Utf8Value exception(tryCatch->Exception()); |   35     v8::String::Utf8Value exception(tryCatch->Exception()); | 
|   36     const char* exceptionString = to_cstring(exception); |   36     const char* exceptionString = to_cstring(exception); | 
|   37     Handle<Message> message = tryCatch->Message(); |   37     v8::Handle<v8::Message> message = tryCatch->Message(); | 
|   38     if (message.IsEmpty()) { |   38     if (message.IsEmpty()) { | 
|   39         // V8 didn't provide any extra information about this error; just |   39         // V8 didn't provide any extra information about this error; just | 
|   40         // print the exception. |   40         // print the exception. | 
|   41         fprintf(stderr, "%s\n", exceptionString); |   41         fprintf(stderr, "%s\n", exceptionString); | 
|   42     } else { |   42     } else { | 
|   43         // Print (filename):(line number): (message). |   43         // Print (filename):(line number): (message). | 
|   44         String::Utf8Value filename(message->GetScriptOrigin().ResourceName()); |   44         v8::String::Utf8Value filename(message->GetScriptOrigin().ResourceName()
     ); | 
|   45         const char* filenameString = to_cstring(filename); |   45         const char* filenameString = to_cstring(filename); | 
|   46         int linenum = message->GetLineNumber(); |   46         int linenum = message->GetLineNumber(); | 
|   47         fprintf(stderr, |   47         fprintf(stderr, | 
|   48                 "%s:%i: %s\n", filenameString, linenum, exceptionString); |   48                 "%s:%i: %s\n", filenameString, linenum, exceptionString); | 
|   49         // Print line of source code. |   49         // Print line of source code. | 
|   50         String::Utf8Value sourceline(message->GetSourceLine()); |   50         v8::String::Utf8Value sourceline(message->GetSourceLine()); | 
|   51         const char* sourceLineString = to_cstring(sourceline); |   51         const char* sourceLineString = to_cstring(sourceline); | 
|   52         fprintf(stderr, "%s\n", sourceLineString); |   52         fprintf(stderr, "%s\n", sourceLineString); | 
|   53         // Print wavy underline. |   53         // Print wavy underline. | 
|   54         int start = message->GetStartColumn(); |   54         int start = message->GetStartColumn(); | 
|   55         for (int i = 0; i < start; i++) { |   55         for (int i = 0; i < start; i++) { | 
|   56             fprintf(stderr, " "); |   56             fprintf(stderr, " "); | 
|   57         } |   57         } | 
|   58         int end = message->GetEndColumn(); |   58         int end = message->GetEndColumn(); | 
|   59         for (int i = start; i < end; i++) { |   59         for (int i = start; i < end; i++) { | 
|   60             fprintf(stderr, "^"); |   60             fprintf(stderr, "^"); | 
|   61         } |   61         } | 
|   62         fprintf(stderr, "\n"); |   62         fprintf(stderr, "\n"); | 
|   63         String::Utf8Value stackTrace(tryCatch->StackTrace()); |   63         v8::String::Utf8Value stackTrace(tryCatch->StackTrace()); | 
|   64         if (stackTrace.length() > 0) { |   64         if (stackTrace.length() > 0) { | 
|   65             const char* stackTraceString = to_cstring(stackTrace); |   65             const char* stackTraceString = to_cstring(stackTrace); | 
|   66             fprintf(stderr, "%s\n", stackTraceString); |   66             fprintf(stderr, "%s\n", stackTraceString); | 
|   67         } |   67         } | 
|   68     } |   68     } | 
|   69 } |   69 } | 
|   70  |   70  | 
|   71 // The callback that implements the JavaScript 'inval' function. |   71 // The callback that implements the JavaScript 'inval' function. | 
|   72 // Invalidates the current window, forcing a redraw. |   72 // Invalidates the current window, forcing a redraw. | 
|   73 // |   73 // | 
|   74 // JS: inval(); |   74 // JS: inval(); | 
|   75 void Global::Inval(const v8::FunctionCallbackInfo<Value>& args) { |   75 void Global::Inval(const v8::FunctionCallbackInfo<v8::Value>& args) { | 
|   76     gGlobal->getWindow()->inval(NULL); |   76     gGlobal->getWindow()->inval(NULL); | 
|   77 } |   77 } | 
|   78  |   78  | 
|   79 // The callback that is invoked by v8 whenever the JavaScript 'print' |   79 // The callback that is invoked by v8 whenever the JavaScript 'print' | 
|   80 // function is called. Prints its arguments on stdout separated by |   80 // function is called. Prints its arguments on stdout separated by | 
|   81 // spaces and ending with a newline. |   81 // spaces and ending with a newline. | 
|   82 // |   82 // | 
|   83 // JS: print("foo", "bar"); |   83 // JS: print("foo", "bar"); | 
|   84 void Global::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { |   84 void Global::Print(const v8::FunctionCallbackInfo<v8::Value>& args) { | 
|   85     bool first = true; |   85     bool first = true; | 
|   86     HandleScope handleScope(args.GetIsolate()); |   86     v8::HandleScope handleScope(args.GetIsolate()); | 
|   87     for (int i = 0; i < args.Length(); i++) { |   87     for (int i = 0; i < args.Length(); i++) { | 
|   88         if (first) { |   88         if (first) { | 
|   89             first = false; |   89             first = false; | 
|   90         } else { |   90         } else { | 
|   91             printf(" "); |   91             printf(" "); | 
|   92         } |   92         } | 
|   93         v8::String::Utf8Value str(args[i]); |   93         v8::String::Utf8Value str(args[i]); | 
|   94         printf("%s", to_cstring(str)); |   94         printf("%s", to_cstring(str)); | 
|   95     } |   95     } | 
|   96     printf("\n"); |   96     printf("\n"); | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
|  107                 v8::String::NewFromUtf8( |  107                 v8::String::NewFromUtf8( | 
|  108                         args.GetIsolate(), "Error: 2 arguments required.")); |  108                         args.GetIsolate(), "Error: 2 arguments required.")); | 
|  109         return; |  109         return; | 
|  110     } |  110     } | 
|  111  |  111  | 
|  112     // Pull out the first arg, make sure it's a function. |  112     // Pull out the first arg, make sure it's a function. | 
|  113     if (!args[0]->IsFunction()) { |  113     if (!args[0]->IsFunction()) { | 
|  114         printf("Not a function passed to setTimeout.\n"); |  114         printf("Not a function passed to setTimeout.\n"); | 
|  115         return; |  115         return; | 
|  116     } |  116     } | 
|  117     Handle<Function> timeoutFn = Handle<Function>::Cast(args[0]); |  117     v8::Handle<v8::Function> timeoutFn = v8::Handle<v8::Function>::Cast(args[0])
     ; | 
|  118  |  118  | 
|  119     double delay = args[1]->NumberValue(); |  119     double delay = args[1]->NumberValue(); | 
|  120     int32_t id = gGlobal->getNextTimerID(); |  120     int32_t id = gGlobal->getNextTimerID(); | 
|  121  |  121  | 
|  122     gGlobal->fTimeouts[id].Reset(gGlobal->fIsolate, timeoutFn); |  122     gGlobal->fTimeouts[id].Reset(gGlobal->fIsolate, timeoutFn); | 
|  123  |  123  | 
|  124     // Create an SkEvent and add it with the right delay. |  124     // Create an SkEvent and add it with the right delay. | 
|  125     SkEvent* evt = new SkEvent(); |  125     SkEvent* evt = new SkEvent(); | 
|  126     evt->setTargetProc(Global::TimeOutProc); |  126     evt->setTargetProc(Global::TimeOutProc); | 
|  127     evt->setFast32(id); |  127     evt->setFast32(id); | 
|  128     evt->postDelay(delay); |  128     evt->postDelay(delay); | 
|  129  |  129  | 
|  130     args.GetReturnValue().Set(Integer::New(gGlobal->fIsolate, id)); |  130     args.GetReturnValue().Set(v8::Integer::New(gGlobal->fIsolate, id)); | 
|  131 } |  131 } | 
|  132  |  132  | 
|  133 // Callback function for SkEvents used to implement timeouts. |  133 // Callback function for SkEvents used to implement timeouts. | 
|  134 bool Global::TimeOutProc(const SkEvent& evt) { |  134 bool Global::TimeOutProc(const SkEvent& evt) { | 
|  135     // Create a handle scope to keep the temporary object references. |  135     // Create a handle scope to keep the temporary object references. | 
|  136     HandleScope handleScope(gGlobal->getIsolate()); |  136     v8::HandleScope handleScope(gGlobal->getIsolate()); | 
|  137  |  137  | 
|  138     // Create a local context from our global context. |  138     // Create a local context from our global context. | 
|  139     Local<Context> context = gGlobal->getContext(); |  139     v8::Local<v8::Context> context = gGlobal->getContext(); | 
|  140  |  140  | 
|  141     // Enter the context so all the remaining operations take place there. |  141     // Enter the context so all the remaining operations take place there. | 
|  142     Context::Scope contextScope(context); |  142     v8::Context::Scope contextScope(context); | 
|  143  |  143  | 
|  144     // Set up an exception handler before calling the Process function. |  144     // Set up an exception handler before calling the Process function. | 
|  145     TryCatch tryCatch; |  145     v8::TryCatch tryCatch; | 
|  146  |  146  | 
|  147     int32_t id = evt.getFast32(); |  147     int32_t id = evt.getFast32(); | 
|  148     if (gGlobal->fTimeouts.find(gGlobal->fLastTimerID) == gGlobal->fTimeouts.end
     ()) { |  148     if (gGlobal->fTimeouts.find(gGlobal->fLastTimerID) == gGlobal->fTimeouts.end
     ()) { | 
|  149         printf("Not a valid timer ID.\n"); |  149         printf("Not a valid timer ID.\n"); | 
|  150         return true; |  150         return true; | 
|  151     } |  151     } | 
|  152  |  152  | 
|  153     const int argc = 0; |  153     const int argc = 0; | 
|  154     Local<Function> onTimeout = |  154     v8::Local<v8::Function> onTimeout = | 
|  155             Local<Function>::New(gGlobal->getIsolate(), gGlobal->fTimeouts[id]); |  155             v8::Local<v8::Function>::New(gGlobal->getIsolate(), gGlobal->fTimeou
     ts[id]); | 
|  156     Handle<Value> result = onTimeout->Call(context->Global(), argc, NULL); |  156     v8::Handle<v8::Value> result = onTimeout->Call(context->Global(), argc, NULL
     ); | 
|  157     gGlobal->fTimeouts.erase(id); |  157     gGlobal->fTimeouts.erase(id); | 
|  158  |  158  | 
|  159     // Handle any exceptions or output. |  159     // Handle any exceptions or output. | 
|  160     if (result.IsEmpty()) { |  160     if (result.IsEmpty()) { | 
|  161         SkASSERT(tryCatch.HasCaught()); |  161         SkASSERT(tryCatch.HasCaught()); | 
|  162         // Print errors that happened during execution. |  162         // Print errors that happened during execution. | 
|  163         gGlobal->reportException(&tryCatch); |  163         gGlobal->reportException(&tryCatch); | 
|  164     } else { |  164     } else { | 
|  165         SkASSERT(!tryCatch.HasCaught()); |  165         SkASSERT(!tryCatch.HasCaught()); | 
|  166         if (!result->IsUndefined()) { |  166         if (!result->IsUndefined()) { | 
|  167             // If all went well and the result wasn't undefined then print the |  167             // If all went well and the result wasn't undefined then print the | 
|  168             // returned value. |  168             // returned value. | 
|  169             String::Utf8Value str(result); |  169             v8::String::Utf8Value str(result); | 
|  170             const char* cstr = to_cstring(str); |  170             const char* cstr = to_cstring(str); | 
|  171             printf("%s\n", cstr); |  171             printf("%s\n", cstr); | 
|  172         } |  172         } | 
|  173     } |  173     } | 
|  174     return true; |  174     return true; | 
|  175 } |  175 } | 
|  176  |  176  | 
|  177 // Creates a new execution environment containing the built-in functions. |  177 // Creates a new execution environment containing the built-in functions. | 
|  178 Handle<Context> Global::createRootContext() { |  178 v8::Handle<v8::Context> Global::createRootContext() { | 
|  179   // Create a template for the global object. |  179   // Create a template for the global object. | 
|  180   Handle<ObjectTemplate> global = ObjectTemplate::New(); |  180   v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); | 
|  181  |  181  | 
|  182   global->Set(v8::String::NewFromUtf8(fIsolate, "print"), |  182   global->Set(v8::String::NewFromUtf8(fIsolate, "print"), | 
|  183               v8::FunctionTemplate::New(fIsolate, Global::Print)); |  183               v8::FunctionTemplate::New(fIsolate, Global::Print)); | 
|  184   global->Set(v8::String::NewFromUtf8(fIsolate, "setTimeout"), |  184   global->Set(v8::String::NewFromUtf8(fIsolate, "setTimeout"), | 
|  185               v8::FunctionTemplate::New(fIsolate, Global::SetTimeout)); |  185               v8::FunctionTemplate::New(fIsolate, Global::SetTimeout)); | 
|  186   global->Set(v8::String::NewFromUtf8(fIsolate, "inval"), |  186   global->Set(v8::String::NewFromUtf8(fIsolate, "inval"), | 
|  187               v8::FunctionTemplate::New(fIsolate, Global::Inval)); |  187               v8::FunctionTemplate::New(fIsolate, Global::Inval)); | 
|  188  |  188  | 
|  189  |  189  | 
|  190   return Context::New(fIsolate, NULL, global); |  190   return v8::Context::New(fIsolate, NULL, global); | 
|  191 } |  191 } | 
|  192  |  192  | 
|  193 void Global::initialize() { |  193 void Global::initialize() { | 
|  194     // Create a stack-allocated handle scope. |  194     // Create a stack-allocated handle scope. | 
|  195     HandleScope handleScope(fIsolate); |  195     v8::HandleScope handleScope(fIsolate); | 
|  196  |  196  | 
|  197     // Create a new context. |  197     // Create a new context. | 
|  198     Handle<Context> context = this->createRootContext(); |  198     v8::Handle<v8::Context> context = this->createRootContext(); | 
|  199  |  199  | 
|  200     // Make the context persistent. |  200     // Make the context persistent. | 
|  201     fContext.Reset(fIsolate, context); |  201     fContext.Reset(fIsolate, context); | 
|  202 } |  202 } | 
|  203  |  203  | 
|  204  |  204  | 
|  205 // Creates the root context, parses the script into it, then stores the |  205 // Creates the root context, parses the script into it, then stores the | 
|  206 // context in a global. |  206 // context in a global. | 
|  207 // |  207 // | 
|  208 // TODO(jcgregorio) Currently only handles one script. Need to move |  208 // TODO(jcgregorio) Currently only handles one script. Need to move | 
|  209 // createRootContext to another call that's only done once. |  209 // createRootContext to another call that's only done once. | 
|  210 bool Global::parseScript(const char script[]) { |  210 bool Global::parseScript(const char script[]) { | 
|  211  |  211  | 
|  212     // Create a stack-allocated handle scope. |  212     // Create a stack-allocated handle scope. | 
|  213     HandleScope handleScope(fIsolate); |  213     v8::HandleScope handleScope(fIsolate); | 
|  214  |  214  | 
|  215     // Get the global context. |  215     // Get the global context. | 
|  216     Handle<Context> context = this->getContext(); |  216     v8::Handle<v8::Context> context = this->getContext(); | 
|  217  |  217  | 
|  218     // Enter the scope so all operations take place in the scope. |  218     // Enter the scope so all operations take place in the scope. | 
|  219     Context::Scope contextScope(context); |  219     v8::Context::Scope contextScope(context); | 
|  220  |  220  | 
|  221     v8::TryCatch tryCatch; |  221     v8::TryCatch tryCatch; | 
|  222  |  222  | 
|  223     // Compile the source code. |  223     // Compile the source code. | 
|  224     Handle<String> source = String::NewFromUtf8(fIsolate, script); |  224     v8::Handle<v8::String> source = v8::String::NewFromUtf8(fIsolate, script); | 
|  225     Handle<Script> compiledScript = Script::Compile(source); |  225     v8::Handle<v8::Script> compiledScript = v8::Script::Compile(source); | 
|  226  |  226  | 
|  227     if (compiledScript.IsEmpty()) { |  227     if (compiledScript.IsEmpty()) { | 
|  228         // Print errors that happened during compilation. |  228         // Print errors that happened during compilation. | 
|  229         this->reportException(&tryCatch); |  229         this->reportException(&tryCatch); | 
|  230         return false; |  230         return false; | 
|  231     } |  231     } | 
|  232  |  232  | 
|  233     // Try running it now to create the onDraw function. |  233     // Try running it now to create the onDraw function. | 
|  234     Handle<Value> result = compiledScript->Run(); |  234     v8::Handle<v8::Value> result = compiledScript->Run(); | 
|  235  |  235  | 
|  236     // Handle any exceptions or output. |  236     // Handle any exceptions or output. | 
|  237     if (result.IsEmpty()) { |  237     if (result.IsEmpty()) { | 
|  238         SkASSERT(tryCatch.HasCaught()); |  238         SkASSERT(tryCatch.HasCaught()); | 
|  239         // Print errors that happened during execution. |  239         // Print errors that happened during execution. | 
|  240         this->reportException(&tryCatch); |  240         this->reportException(&tryCatch); | 
|  241         return false; |  241         return false; | 
|  242     } |  242     } | 
|  243  |  243  | 
|  244     return true; |  244     return true; | 
|  245 } |  245 } | 
| OLD | NEW |