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